﻿using AutoMapper;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using QMERP.Domain.Dtos;
using QMERP.Domain.Entities;
using QMERP.Domain.Enums;
using QMERP.Domain.ImportModels;
using QMERP.Domain.PrintModels;
using QMERP.Infrastructure.CustomException;
using QMERP.Infrastructure.EFCore;
using QMERP.Infrastructure.EFCore.Extensions;
using QMERP.Infrastructure.Extensions;
using QMERP.Infrastructure.Security;
using QMERP.Infrastructure.Tools;
using System.Data;

namespace QMERP.Application.Services
{
    public class RetailOrderService : IRetailOrderService
    {
        private readonly IMapper _mapper;
        private readonly QMERPDbContext _db;
        private readonly ISerialNumberService _serialNumberSvc;
        private readonly ICurrentUser _currentUser;
        private readonly ILeaveStockOrderService _leaveStockOrderSvc;
        private readonly IWebHostEnvironment _webHostEnvironment;
        public RetailOrderService(IMapper mapper, QMERPDbContext db, ISerialNumberService serialNumberSvc, ICurrentUser currentUser, ILeaveStockOrderService leaveStockOrderSvc, IWebHostEnvironment webHostEnvironment)
        {
            _mapper = mapper;
            _db = db;
            _serialNumberSvc = serialNumberSvc;
            _currentUser = currentUser;
            _leaveStockOrderSvc = leaveStockOrderSvc;
            _webHostEnvironment = webHostEnvironment;
        }
        /// <summary>
        /// 散镜订单窗体
        /// </summary>
        /// <returns></returns>
        public async Task<PageResponse<RetailOrderResponse>> Query(PageRequest<RetailOrderRequest> request)
        {
            var response = new PageResponse<RetailOrderResponse>();
            var query = Where(request);
            var list = await query.Paging(request.PageIndex, request.PageSize).ToListAsync();
            response.TotalCount = await query.CountAsync();
            response.PageIndex = request.PageIndex;
            response.PageSize = request.PageSize;
            response.List = _mapper.Map<List<RetailOrderResponse>>(list);
            return response;
        }
        /// <summary>
        /// 获取id的散镜订单详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<RetailOrderResponse> Detail(long id)
        {
            var model = await _db.RetailOrder.Include(x => x.Contract).Include(x => x.Customer)
                .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Contract_Lens).ThenInclude(x => x!.Lens)
                .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Warehouse).AsNoTracking().FindByIdAsync(id);
            var response = _mapper.Map<RetailOrderResponse>(model);
            return response;
        }
        /// <summary>
        /// 散镜订单保存
        /// </summary>
        /// <param name="request"></param>
        /// <param name="isCheck"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task<RetailOrderResponse> Save(RetailOrderSaveRequest request, bool isCheck = false)
        {
            if (request.RetailOrderDetails.Count <= 0)
                throw new ApiException("请填写镜种信息!");

            if (request.CustomerOrderNumber.IsNullOrWhiteSpace())
                throw new ApiException($"客户单号不能为空!");

            if (await _db.RetailOrder.AnyAsync(x => x.CustomerOrderNumber.ToLower() == request.CustomerOrderNumber.ToLower() && x.Id != request.Id))
                throw new ApiException($"客户单号{request.CustomerOrderNumber}已存在!");

            for (int i = 0; i < request.RetailOrderDetails.Count; i++)
            {
                string col = $"第{i + 1}行:";
                var detail = request.RetailOrderDetails[i];
                string degreesType = "-/-";
                if (detail.SPH > 0)
                    degreesType = "+/-";
                detail.DegreesType = degreesType;


                var stock = await (from a in _db.Stock.Include(x => x.StockDetails).Include(x => x.Warehouse)
                                   join b in _db.Contract_Lens on a.LensId equals b.LensId
                                   where b.ContractId == request.ContractId && a.WarehouseId == detail.WarehouseId && b.Id == detail.Contract_LensId
                                   select a
                     ).FirstOrDefaultAsync();

                if (stock == null)
                    throw new ApiException($"{col}此仓库的库存镜种不存在!");

                if (detail.Qty <= 0)
                    throw new ApiException($"{col}片数为0,请检查!");

                var contract_Lens = await _db.Contract_Lens.Include(x => x.Lens).FindByIdAsync(detail.Contract_LensId);

                if (!(detail.SPH >= contract_Lens?.MinSPH && detail.SPH <= contract_Lens?.MaxSPH && detail.CYL >= contract_Lens?.MinSPH && detail.CYL <= contract_Lens?.MaxCYL))
                {
                    throw new ApiException($"{col}度数超出镜种范围内!");
                }
                var stockDetail = stock.GetByRange(detail.DegreesType, detail.SPH, detail.CYL);
                if (stockDetail.Qty - detail.Qty < 0)
                {
                    throw new ApiException($"{col}仓库{stock.Warehouse?.Code}镜种{contract_Lens?.Lens?.SalesLensCode}度数SPH:{detail.SPH},CYL{detail.CYL}库存片数不足扣库");
                }
            }

            RetailOrder? model = _mapper.Map<RetailOrder>(request);
            if (request.Id != null)
            {
                model = await _db.RetailOrder.Include(x => x.RetailOrderDetails).FindByIdAsync(request.Id.Value);
                if (model == null)
                    throw new ApiException("散镜订单不存在!");
                model.CustomerOrderNumber = request.CustomerOrderNumber;
                model.TrayNumber = request.TrayNumber;
                model.DeliveryOn = request.DeliveryOn;
                model.OutRank = request.OutRank;
                model.CustomerId = request.CustomerId;
                model.ContractId = request.ContractId;
                model.Remark = request.Remark;

                model.Coating = request.Coating;
                model.TintingColor = request.TintingColor;
                model.Mirror = request.Mirror;
                model.TintingCode = request.TintingCode;
                model.TintingName = request.TintingName;
                model.UV = request.UV;
                model.PaoGuang = request.PaoGuang;
                model.CaiBian = request.CaiBian;
                model.Hard = request.Hard;
                model.CheBian = request.CheBian;
                model.KaiKeng = request.KaiKeng;
                model.PiHua = request.PiHua;
                model.ZuanKong = request.ZuanKong;
                model.Frame = request.Frame;
                //model.RetailOrderDetails = _mapper.Map<List<RetailOrderDetail>>(request.RetailOrderDetails);
            }
            var salesProcesses = await _db.SalesProcess.Where(x => x.IsKCUsable).ToListAsync();
            model.RetailOrderDetails = _mapper.Map<List<RetailOrderDetail>>(request.RetailOrderDetails);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.Coating, request.RetailOrderSalesProcess.Coating);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.TintingColor, request.RetailOrderSalesProcess.TintingColor);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.Mirror, request.RetailOrderSalesProcess.Mirror);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.TintingCode, request.RetailOrderSalesProcess.TintingCode);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.TintingName, request.RetailOrderSalesProcess.TintingName);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.UV, request.RetailOrderSalesProcess.UV);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.Frame, request.RetailOrderSalesProcess.Frame);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.Hard, request.RetailOrderSalesProcess.Hard);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.PaoGuang, request.RetailOrderSalesProcess.PaoGuang);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.CaiBian, request.RetailOrderSalesProcess.CaiBian);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.CheBian, request.RetailOrderSalesProcess.CheBian);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.KaiKeng, request.RetailOrderSalesProcess.KaiKeng);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.PiHua, request.RetailOrderSalesProcess.PiHua);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.KnifeEdge, request.RetailOrderSalesProcess.KnifeEdge);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.Base, request.RetailOrderSalesProcess.Base);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.ZuanKong, request.RetailOrderSalesProcess.ZuanKong);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.OtherProcess, request.RetailOrderSalesProcess.OtherProcess);
            //SetProcess(model, salesProcesses, SalesProcessesTypeEnum.ExtraProcess, request.RetailOrderSalesProcess.ExtraProcess);
            if (request.Id == null)
            {
                string number = await _serialNumberSvc.GetSerialNumber(SerialNumberTypeEnum.RetailOrder);
                model.Number = number;
                model.Status = RetailOrderStatusEnum.Pending.ToString();
                await _db.AddAsync(model);
            }
            await _db.SaveChangesAsync();
            if (isCheck)
            {
                model = await _db.RetailOrder
                 .Include(x => x.Contract).Include(x => x.Customer)
                 .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Contract_Lens).ThenInclude(x => x!.Lens)
                 .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Warehouse).FindByIdAsync(model.Id);
                if (model != null)
                {
                    await Check(model);
                    await _db.SaveChangesAsync();
                }
            } 
            return _mapper.Map<RetailOrderResponse>(model);
        }
        /// <summary>
        /// 散镜订单审核
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task Check(long[] ids)
        {
            if (ids == null)
                throw new ApiException("id不能为空!");

            var list = await _db.RetailOrder.Where(x => ids.Contains(x.Id)).ToListAsync();
            foreach (var order in list)
            {
                if (order.Status != RetailOrderStatusEnum.Pending.ToString())
                    throw new ApiException($"散镜订单{order.Number}不能审核!");

                await Check(order);
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 散镜订单弃审
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task UnCheck(long[] ids)
        {
            if (ids == null)
                throw new ApiException("id不能为空!");

            var list = await _db.RetailOrder.Where(x => ids.Contains(x.Id)).ToListAsync();
            foreach (var order in list)
            {
                if (order.Status != RetailOrderStatusEnum.Delivery.ToString())
                    throw new ApiException($"散镜订单{order.Number}不能弃审!");

                if (await _db.LeaveStockOrder.AnyAsync(x => x.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.RetailOrder.ToString() && x.BusinessOrderId == order.Id && x.Status != LeaveStockOrderStatusEnum.Canceled.ToString()))
                    throw new ApiException($"散镜订单{order.Number}不能弃审,已添加出库单!");

                order.Status = RetailOrderStatusEnum.Pending.ToString();
                order.CheckedBy = null;
                order.CheckedByName = null;
                order.CheckedOn = null;
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 散镜订单取消
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task Cancel(long[] ids)
        {
            if (ids == null)
                throw new ApiException("id不能为空!");

            var list = await _db.RetailOrder.Where(x => ids.Contains(x.Id)).ToListAsync();
            foreach (var order in list)
            {
                if (order.Status != RetailOrderStatusEnum.Pending.ToString() || order.Status != RetailOrderStatusEnum.Delivery.ToString())
                    throw new ApiException($"散镜订单{order.Number}不能取消!");

                if (await _db.LeaveStockOrder.AnyAsync(x => x.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.RetailOrder.ToString() && x.BusinessOrderId == order.Id && x.Status != LeaveStockOrderStatusEnum.Canceled.ToString()))
                    throw new ApiException($"散镜订单{order.Number}不能取消,已添加出库单!");

                order.Status = RetailOrderStatusEnum.Canceled.ToString();
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 散镜订单完成
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task Finish(long[] ids)
        {
            if (ids == null)
                throw new ApiException("id不能为空!");

            var list = await _db.RetailOrder.Where(x => ids.Contains(x.Id)).ToListAsync();
            foreach (var order in list)
            {
                if (order.Status != RetailOrderStatusEnum.Delivered.ToString())
                    throw new ApiException($"散镜订单{order.Number}不能完成!");

                order.Status = RetailOrderStatusEnum.Finished.ToString();
                order.FinishedBy = _currentUser.Id;
                order.FinishedByName = _currentUser.Name;
                order.FinishedOn = DateTime.Now;
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 获取发票数据
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<List<RetailOrderInvoice>> GetInvoices(long[] ids)
        {
            var orders = await _db.RetailOrder.Include(x => x.Contract).Include(x => x.Customer)
                .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Contract_Lens).ThenInclude(x => x!.Lens)
                .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Warehouse).AsNoTracking().Where(x => ids.Contains(x.Id)).ToListAsync();
            if (orders.Count <= 0)
            {
                throw new ApiException("散镜订单不存在!");
            }
            List<RetailOrderInvoice> retailOrderInvoices = new();
            foreach (var order in orders)
            {
                List<RetailOrderDetail> retailOrderDetails = order.RetailOrderDetails.ToList();
                var detailR = retailOrderDetails[0];
                var detailL = retailOrderDetails[1];
                RetailOrderInvoice retailOrderInvoice = new()
                {
                    OrderNumber = order.Number,
                    CustomerOrderNumber = order.CustomerOrderNumber,
                    CustomerCode = order.Customer!.Code,
                    CustomerName = order.Customer!.Name,
                    BillingAddress = order.Customer!.BillingAddress,
                    Telephone = order.Customer!.Telephone,
                    SalesLensCodeR = detailR.Contract_Lens!.Lens!.SalesLensCode,
                    FactoryLensCodeR = detailR.Contract_Lens!.Lens!.FactoryLensCode,
                    SPHR = detailR.SPH,
                    CYLR = detailR.CYL,
                    AxisR = detailR.Axis,
                    QtyR = detailR.Qty,
                    SalesLensCodeL = detailL.Contract_Lens!.Lens!.SalesLensCode,
                    FactoryLensCodeL = detailL.Contract_Lens!.Lens!.FactoryLensCode,
                    SPHL = detailL.SPH,
                    CYLL = detailL.CYL,
                    AxisL = detailL.Axis,
                    QtyL = detailL.Qty,
                    CreatedByName = order.CreatedByName,
                };
                retailOrderInvoices.Add(retailOrderInvoice);
            }
            return retailOrderInvoices;
        }
        /// <summary>
        /// 批量出库
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<List<LeaveStockOrderResponse>> BatchLeaveStock(long[] ids)
        {
            var list = await _db.RetailOrder.Include(x => x.Contract).Include(x => x.Customer)
                .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Contract_Lens).ThenInclude(x => x!.Lens)
                .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Warehouse).AsNoTracking().Where(x => ids.Contains(x.Id)).ToListAsync();
            var orderList = new List<LeaveStockOrderResponse>();
            foreach (var retailOrder in list)
            {
                var order = new LeaveStockOrderSaveRequest()
                {
                    BusinessOrderId = retailOrder.Id,
                    BusinessOrderNumber = retailOrder.Number,
                    BusinessOrderType = LeaveStockBusinessOrderTypeEnum.RetailOrder.ToString(),
                    BusinessType = LeaveStockBusinessTypeEnum.SalesLeaveStock.ToString(),
                };
                var lenses = retailOrder.RetailOrderDetails.Select(s => new { s.WarehouseId, s.Contract_LensId }).Distinct().ToList();
                foreach (var lens in lenses)
                {
                    var retailOrderDetails = retailOrder.RetailOrderDetails.Where(x => x.WarehouseId == lens.WarehouseId && x.Contract_LensId == lens.Contract_LensId).ToList();

                    if (retailOrderDetails != null && retailOrderDetails.Count > 0)
                    {
                        var ranges = retailOrder.RetailOrderDetails.Where(x => x.WarehouseId == lens.WarehouseId && x.Contract_LensId == lens.Contract_LensId).Select(s => new { s.SPH, s.CYL }).Distinct().ToList();
                        foreach (var range in ranges)
                        {
                            var details = retailOrderDetails.Where(x => x.SPH == range.SPH && x.CYL == range.CYL).ToList();
                            List<LensDetailResponse> lensDetails = new()
                                {
                                    new LensDetailResponse()
                                    {
                                        DegreesType = details[0].DegreesType,
                                        SPH = details[0].SPH,
                                        CYL = details[0].CYL,
                                        ADD = details[0].ADD,
                                        Qty = details.Sum(s => s.Qty),
                                    }
                                };
                            LeaveStockOrderDetailSaveRequest leaveStockOrderDetail = new()
                            {
                                WarehouseId = details[0].Warehouse!.Id,
                                LensId = details[0].Contract_Lens!.LensId,
                                LensDetails = lensDetails
                            };
                            order.LeaveStockOrderDetails.Add(leaveStockOrderDetail);
                        }

                    }
                }
                orderList.Add(await _leaveStockOrderSvc.Save(order));
            }
            return orderList;
        }
        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task Import(RetailOrderImportRequest request)
        {
            if (request.File == null)
                throw new ApiException("文件不能为空!");
            Stream stream = request.File.OpenReadStream();
            var contract = await _db.Contract.Include(x => x.Contract_Customers).ThenInclude(x => x.Customer).Include(x => x.Contract_Lenses).ThenInclude(x => x.Lens).FindByIdAsync(request.ContractId);
            if (contract == null)
                throw new ApiException("合约不存在!");
            List<RetailOrderSaveRequest> orders = new();
            if (request.ImportFormat == RetailOrderImportFormatEnum.AS系列.ToString())
            {
                List<ASFormat> asFormats = ExcelHelper.ExcelStreamToDataTable(stream).ToList<ASFormat>();
                asFormats = asFormats.Where(x => x.ORDER_NO != "").ToList();
                orders = _mapper.Map<List<RetailOrderSaveRequest>>(asFormats);
                foreach (var order in orders)
                {
                    var customerNumber = order.CustomerOrderNumber.Split('-').LastOrDefault();
                    if (customerNumber != null)
                    {
                        order.CustomerOrderNumber = customerNumber;
                        var customerCode = customerNumber[..5];
                        var contract_Customer = contract.Contract_Customers.Where(x => x.Customer!.Code == customerCode).FirstOrDefault();
                        if (contract_Customer == null)
                            throw new ApiException($"客户代号{customerCode}不在合约绑定的客户列表里!");
                        order.CustomerId = contract_Customer.CustomerId;
                    }
                }
            }
            else if (request.ImportFormat == RetailOrderImportFormatEnum.HKEGG.ToString())
            {
                //List<HKEGGFormat> hkeggFormats = ExcelHelper.ExcelStreamToDataTable(stream).ToList<HKEGGFormat>();
                //orders = _mapper.Map<List<RetailOrderSaveRequest>>(hkeggFormats);
            }
            else if (request.ImportFormat == RetailOrderImportFormatEnum.MDGlass.ToString())
            {
                List<MDGlassFormat> mdGlassFormats = ExcelHelper.ExcelStreamToDataTable(stream).ToList<MDGlassFormat>();
                mdGlassFormats = mdGlassFormats.Where(x => x.客戶單號 != "").ToList();
                orders = _mapper.Map<List<RetailOrderSaveRequest>>(mdGlassFormats);
                foreach (var order in orders)
                {
                    var contract_Customer = contract.Contract_Customers.Where(x => x.Customer!.Code == order.CustomerCode).FirstOrDefault();
                    if (contract_Customer == null)
                        throw new ApiException($"客户代号{order.CustomerCode}不在合约绑定的客户列表里!");
                    order.CustomerId = contract_Customer.CustomerId;
                }
            }
            if (orders.Count > 0)
            {
                foreach (var order in orders)
                {
                    order.ContractId = request.ContractId;

                    var detailR = order.RetailOrderDetails.Where(x => x.EyeType == EyeTypeEnum.R.ToString()).FirstOrDefault();
                    var detailL = order.RetailOrderDetails.Where(x => x.EyeType == EyeTypeEnum.L.ToString()).FirstOrDefault();
                    if (detailR != null)
                    {
                        await SetContractLens(order, detailR, contract, request.WarehouseId);
                    }
                    if (detailL != null)
                    {
                        await SetContractLens(order, detailL, contract, request.WarehouseId);
                    }
                    await Save(order);
                }
            }

        }
        private async Task SetContractLens(RetailOrderSaveRequest order, RetailOrderDetailSaveRequest detail, Domain.Entities.Contract contract, long warehouseId)
        {
            var contractLens = contract.Contract_Lenses.Where(x => x.Lens!.SalesLensCode == detail.SalesLensCode).FirstOrDefault();
            if (contractLens == null)
                throw new ApiException($"{order.CustomerOrderNumber}的{detail.EyeType}镜种{detail.SalesLensCode}不在合约中!");
            var stock = await _db.Stock.Include(x => x.Lens).Where(x => x.Lens!.SalesLensCode == detail.SalesLensCode && x.WarehouseId == warehouseId).FirstOrDefaultAsync();
            if (stock == null)
                throw new ApiException($"{order.CustomerOrderNumber}的{detail.EyeType}镜种{detail.SalesLensCode}不在库存中!");
            detail.Contract_LensId = contractLens.Id;
            detail.WarehouseId = warehouseId;
        }
        /// <summary>
        /// 获取散镜订单主要信息列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<List<RetailOrderMainInfoResponse>> GetRetailOrderMainInfos(PageRequest<RetailOrderRequest> request)
        {
            var orders = await Where(request).ToListAsync();
            var details = orders.SelectMany(s => s.RetailOrderDetails).ToList();
            return _mapper.Map<List<RetailOrderMainInfoResponse>>(details);
        }
        private IQueryable<RetailOrder> Where(PageRequest<RetailOrderRequest> request)
        {
            IQueryable<RetailOrder> query = _db.RetailOrder
                .Include(x => x.Contract).Include(x => x.Customer)
                .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Contract_Lens).ThenInclude(x => x!.Lens)
                .Include(x => x.RetailOrderDetails).ThenInclude(x => x.Warehouse).AsNoTracking();
            if (!request.Query.Number.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Number.Contains(request.Query.Number!));
            }
            if (!request.Query.RelationNumber.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.RelationNumber!.Contains(request.Query.RelationNumber!));
            }
            if (!request.Query.CustomerOrderNumber.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.CustomerOrderNumber.Contains(request.Query.CustomerOrderNumber!));
            }
            if (!request.Query.TrayNumber.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.TrayNumber!.Contains(request.Query.TrayNumber!));
            }
            if (request.Query.InvoicePrintOnStart != null)
            {
                query = query.Where(x => x.InvoicePrintOn >= request.Query.InvoicePrintOnStart);
            }
            if (request.Query.InvoicePrintEndOn != null)
            {
                query = query.Where(x => x.InvoicePrintOn <= request.Query.InvoicePrintEndOn);
            }
            if (!request.Query.CreatedByName.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.CreatedByName.Contains(request.Query.CreatedByName!));
            }
            if (request.Query.CreatedOnStart != null)
            {
                query = query.Where(x => x.CreatedOn >= request.Query.CreatedOnStart.Value.ToStart());
            }
            if (request.Query.CreatedOnEnd != null)
            {
                query = query.Where(x => x.CreatedOn <= request.Query.CreatedOnEnd.Value.ToEnd());
            }
            if (request.Query.CustomerId != null)
            {
                query = query.Where(x => x.CustomerId == request.Query.CustomerId);
            }
            if (request.Query.WarehouseId != null)
            {
                query = query.Where(x => x.RetailOrderDetails.Select(s => s.WarehouseId).Contains(request.Query.WarehouseId.Value));
            }
            if (request.Query.LensId != null)
            {
                query = query.Where(x => x.RetailOrderDetails.Select(s => s.Contract_Lens!.LensId).Contains(request.Query.LensId.Value));
            }
            if (!request.Query.Status.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Status == request.Query.Status);
            }
            //if (request.Query.Status == RetailOrderStatusEnum.Pending.ToString())
            //{
            //    query = query.OrderByDescending(x => x.CreatedOn);
            //}
            //else if (request.Query.Status == RetailOrderStatusEnum.Checked.ToString())
            //{
            //    query = query.OrderByDescending(x => x.CheckedOn);
            //}
            //else if (request.Query.Status == RetailOrderStatusEnum.Finished.ToString())
            //{
            //    query = query.OrderByDescending(x => x.FinishedOn);
            //}
            //else
            //{
            //    query = query.OrderByDescending(x => x.UpdatedOn);
            //}
            query = query.OrderByDescending(x => x.CreatedOn);
            return query;
        }
        private void SetProcess(RetailOrder retailOrder, List<SalesProcess> salesProcesses, SalesProcessesTypeEnum salesProcessesType, object? value = null)
        {
            //if (value != null)
            //{
            //    string v = value.ToString()!;
            //    var salesProcess = salesProcesses.FirstOrDefault(x => x.Code == salesProcessesType.ToString() && x.Name == v);
            //    if (bool.TryParse(v, out bool isBool))
            //    {
            //        if (isBool)
            //            salesProcess = salesProcesses.FirstOrDefault(x => x.Code == salesProcessesType.ToString());
            //        else
            //            return;
            //    }
            //    if (salesProcess == null)
            //    {
            //        throw new ApiException($"{salesProcessesType}工序不存在!");
            //    }
            //    var detail_process = new RetailOrder_SalesProcess()
            //    {
            //        SalesProcessId = salesProcess.Id,
            //    };
            //    retailOrder.RetailOrder_SalesProcesses.Add(detail_process);
            //}

        }
        private async Task Check(RetailOrder order)
        {
            foreach (var detail in order.RetailOrderDetails)
            {
                var stock = await _db.Stock.GetByWarehouseLens(detail.WarehouseId, detail.Contract_Lens!.LensId);
                var stockDetail = stock.GetByRange(detail.DegreesType, detail.SPH, detail.CYL);
                if (stockDetail.Qty - detail.Qty < 0)
                {
                    throw new ApiException($"散镜订单号{order.Number}的仓库{detail.Warehouse?.Code}镜种{detail.Contract_Lens.Lens?.SalesLensCode}度数SPH:{detail.SPH},CYL{detail.CYL}库存片数不足扣库");
                }
            }
            order.Status = RetailOrderStatusEnum.Delivery.ToString();
            order.CheckedBy = _currentUser.Id;
            order.CheckedByName = _currentUser.Name;
            order.CheckedOn = DateTime.Now;
        }
    }
}